using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication1
{
    public partial class DisplayArea : ScrollableControl
    {
        TileEditorForm parent;
        Point mouseLocation = new Point(0, 0);
        public DisplayArea()
        {
            InitializeComponent();
        }

        public void SetParent(TileEditorForm _parent)
        {
            parent = _parent;
        }

        public void Redraw()
        {
            // Do nothing if there is no parent set. A parent's information is needed to draw.
            if (parent != null)
            {
                SGD.ManagedDirect3D.Instance.Clear(255, 255, 255);
                // Checks which layer to start rendering at.
                int firstLayerToRender = parent.List_Layers.SelectedIndex;
                if (parent.Checkbox_ShowBehind.Checked || firstLayerToRender < 0)
                    firstLayerToRender = 0;
                // Enters a loop to render all of the layers to the screen.
                SGD.ManagedDirect3D.Instance.DeviceBegin();
                for (int i = firstLayerToRender; i <= parent.List_Layers.SelectedIndex; i++)
                {
                    Layer currentLayer = parent.List_Layers.Items[i] as Layer;
                    Rectangle gridRect = Rectangle.Empty;
                    List<Point> arrows = new List<Point>();
                    for (int w = (-AutoScrollPosition.X / parent.level.TileWidth); w < Math.Min(((Width - AutoScrollPosition.X) / parent.level.TileWidth), parent.level.BoardWidth)+1; w++)
                    {
                        for (int h = (-AutoScrollPosition.Y / parent.level.TileHeight); h < Math.Min(((Height - AutoScrollPosition.Y) / parent.level.TileHeight), parent.level.BoardHeight)+1; h++)
                        {
                            Tile currentTile = currentLayer.GetElement(w, h);
                            if (currentTile != null)
                            {
                                if (currentTile.CurrentBitmap != null)
                                {
                                    SGD.ManagedDirect3D.Instance.SpriteBegin();
                                    SGD.ManagedTextureManager.Instance.Draw(0, (w * parent.level.TileWidth) + AutoScrollPosition.X, (h * parent.level.TileHeight) + AutoScrollPosition.Y, 1, 1, new Rectangle(currentTile.TileLocation.X * parent.level.TileWidth, currentTile.TileLocation.Y * parent.level.TileHeight, parent.level.TileWidth, parent.level.TileHeight), 0, 0, 0, Color.FromArgb(255, 255, 255).ToArgb());
                                    SGD.ManagedDirect3D.Instance.SpriteEnd();
                                }
                                SGD.ManagedDirect3D.Instance.LineBegin();
                                if (currentTile.Collision == (int)Tile.CollisionTypes.COLLISION)
                                    SGD.ManagedDirect3D.Instance.DrawRect(new Rectangle((w * parent.level.TileWidth) + AutoScrollPosition.X, (h * parent.level.TileHeight) + AutoScrollPosition.Y, parent.level.TileWidth, parent.level.TileHeight), 200, 50, 50);
                                if (currentTile.Collision == (int)Tile.CollisionTypes.LADDER)
                                    SGD.ManagedDirect3D.Instance.DrawRect(new Rectangle((w * parent.level.TileWidth) + AutoScrollPosition.X, (h * parent.level.TileHeight) + AutoScrollPosition.Y, parent.level.TileWidth, parent.level.TileHeight), 130, 200, 130);
                                if (currentTile.Collision == (int)Tile.CollisionTypes.DOOR)
                                {
                                    SGD.ManagedDirect3D.Instance.DrawRect(new Rectangle((w * parent.level.TileWidth) + AutoScrollPosition.X, (h * parent.level.TileHeight) + AutoScrollPosition.Y, parent.level.TileWidth, parent.level.TileHeight), 230, 210, 100);
                                    arrows.Add(new Point(w, h));
                                    arrows.Add(new Point(currentTile.DoorTo.X, currentTile.DoorTo.Y));
                                }
                                SGD.ManagedDirect3D.Instance.LineEnd();
                            }
                            if (currentLayer.GetLayerType() == 0 && parent.level.doorToAdd.X > -1 && parent.level.doorToAdd.X == w && parent.level.doorToAdd.Y == h)
                            {
                                SGD.ManagedDirect3D.Instance.DrawRect(new Rectangle((w * parent.level.TileWidth) + AutoScrollPosition.X, (h * parent.level.TileHeight) + AutoScrollPosition.Y, parent.level.TileWidth, parent.level.TileHeight), 230, 210, 100);
                            }
                            if (parent.Checkbox_ShowGrid.Checked)
                            {
                                SGD.ManagedDirect3D.Instance.LineBegin();
                                SGD.ManagedDirect3D.Instance.DrawRect(new Rectangle((w * parent.level.TileWidth) + AutoScrollPosition.X, 0, 1, (parent.level.TileHeight * parent.level.BoardHeight)), 150, 150, 150);
                                SGD.ManagedDirect3D.Instance.DrawRect(new Rectangle(0, (h * parent.level.TileHeight) + AutoScrollPosition.Y, (parent.level.TileWidth * parent.level.BoardWidth), 1), 150, 150, 150);
                                SGD.ManagedDirect3D.Instance.LineEnd();
                            }
                        }
                    }
                    if (parent.Checkbox_ShowSpawnPoints.Checked)
                    {
                        for (int j = 0; j < parent.List_SpawnPoints.Items.Count; j++)
                        {
                            SpawnPoints _spawn = parent.List_SpawnPoints.Items[j] as SpawnPoints;
                            SGD.ManagedDirect3D.Instance.LineBegin();
                            Rectangle _rect = new Rectangle(_spawn.Location.X+AutoScrollPosition.X - 5, _spawn.Location.Y+AutoScrollPosition.Y - 5, 10, 10);
                            if (j == parent.List_SpawnPoints.SelectedIndex)
                                SGD.ManagedDirect3D.Instance.DrawRect(new Rectangle(_rect.X - 3, _rect.Y - 3, _rect.Width + 6, _rect.Height + 6), 0, 0, 0);
                            if (_spawn.Type <= (int)SpawnPoints.Characters.SURVIVOR_RESPAWN)
                                SGD.ManagedDirect3D.Instance.DrawRect(_rect, 200, 100, 100);
                            else
                                SGD.ManagedDirect3D.Instance.DrawRect(_rect, 0, 150, 0);
                            SGD.ManagedDirect3D.Instance.LineEnd();
                        }
                    }
                    for (int z = 0; z < arrows.Count; z+=2)
                    {
                        SGD.ManagedDirect3D.Instance.LineBegin();
                        int x1 = (arrows[z].X*parent.level.TileWidth)+(parent.level.TileWidth/2);
                        int x2 = (arrows[z + 1].X*parent.level.TileWidth)+(parent.level.TileWidth/2);
                        int y1 = (arrows[z].Y*parent.level.TileHeight)+(parent.level.TileHeight/2);
                        int y2 = (arrows[z + 1].Y * parent.level.TileHeight)+(parent.level.TileHeight/2);
                        SGD.ManagedDirect3D.Instance.DrawLine(x1, y1, x2, y2, 230, 210, 100);
                        SGD.ManagedDirect3D.Instance.LineEnd();
                    }
                }
                SGD.ManagedDirect3D.Instance.DeviceEnd();
                SGD.ManagedDirect3D.Instance.Present();
                /*PaintEventArgs pe = new PaintEventArgs(Graphics.FromHwnd(this.Handle), new Rectangle(0, 0, this.Width, this.Height));
                Bitmap _bitmap = Properties.Resources.Bill;
                _bitmap.MakeTransparent(Color.White);
                pe.Graphics.DrawImage(_bitmap, mouseLocation);
                pe.Dispose();*/
            }
        }
        protected override void OnPaint(PaintEventArgs pe)
        {
            Redraw();
        }
        void Paint_Brush(Layer _layer, Tile _tile, int _x, int _y)
        {
            _layer.SetElement(_x, _y, _tile.CurrentBitmap, _tile.TileLocation, _tile.Collision, new Point(-1, -1));
        }
        void Paint_Fill(Layer _layer, Tile _newTile, Tile _oldTile, int _x, int _y)
        {
            if (_x < 0 || _y < 0 || _x >= parent.level.BoardWidth || _y >= parent.level.BoardHeight)
                return;
            Tile temp;
            temp = _layer.GetElement(_x, _y);
            if (temp == _newTile || (temp != null && temp.IsEqual(_newTile)))
                return;
            _layer.SetElement(_x, _y, _newTile.CurrentBitmap, _newTile.TileLocation, _newTile.Collision, new Point(-1, -1));
            for (int num = -1; num <= 1; num += 2)
            {
                temp = _layer.GetElement(_x + num, _y);
                if (temp == _oldTile || (temp != null && temp.IsEqual(_oldTile)))
                    Paint_Fill(_layer, _newTile, _oldTile, _x + num, _y);
                temp = _layer.GetElement(_x, _y + num);
                if (temp == _oldTile || (temp != null && temp.IsEqual(_oldTile)))
                    Paint_Fill(_layer, _newTile, _oldTile, _x, _y + num);
            }
        }
        void SetTiles(MouseEventArgs e)
        {
            Layer currentLayer = parent.List_Layers.Items[parent.List_Layers.SelectedIndex] as Layer;
            int _x = (int)((e.X - this.AutoScrollPosition.X) / parent.level.TileWidth);
            int _y = (int)((e.Y - this.AutoScrollPosition.Y) / parent.level.TileHeight);
            if (_x < 0 || _y < 0 || _x >= parent.level.BoardWidth || _y >= parent.level.BoardHeight)
                return;
            if (parent.FillType_Brush.Checked)
            {
                if (e.Button == MouseButtons.Left)
                {
                    if (currentLayer.GetLayerType() == 1)
                    {
                        if (parent.List_Tilesets.SelectedIndex > -1)
                        {
                            LoadedBitmap currentBitmap = parent.List_Tilesets.Items[parent.List_Tilesets.SelectedIndex] as LoadedBitmap;
                            Paint_Brush(currentLayer, new Tile(currentBitmap, new Point(parent.Custom_TilePicker.GetSelected().X, parent.Custom_TilePicker.GetSelected().Y), (int)Tile.CollisionTypes.NO_COLLISION), _x, _y);
                        }
                    }
                    else
                        Paint_Brush(currentLayer, new Tile(null, new Point(parent.Custom_TilePicker.GetSelected().X, parent.Custom_TilePicker.GetSelected().Y), parent.Custom_TilePicker.GetSelected().Y), _x, _y);
                }
                if (e.Button == MouseButtons.Right)
                    Paint_Brush(currentLayer, new Tile(null, new Point(0, 0), (int)Tile.CollisionTypes.NO_COLLISION), _x, _y);
            }
            else if (parent.FillType_PaintBucket.Checked)
            {
                Tile oldTile = new Tile(currentLayer.GetElement(_x, _y).CurrentBitmap, currentLayer.GetElement(_x, _y).TileLocation, currentLayer.GetElement(_x, _y).Collision);
                if (e.Button == MouseButtons.Left)
                {
                    if (currentLayer.GetLayerType() == 1)
                    {
                        if (parent.List_Tilesets.SelectedIndex > -1)
                        {
                            LoadedBitmap currentBitmap = parent.List_Tilesets.Items[parent.List_Tilesets.SelectedIndex] as LoadedBitmap;
                            Paint_Fill(currentLayer, new Tile(currentBitmap, new Point(parent.Custom_TilePicker.GetSelected().X, parent.Custom_TilePicker.GetSelected().Y), (int)Tile.CollisionTypes.NO_COLLISION), oldTile, _x, _y);
                        }
                    }
                    else
                        Paint_Fill(currentLayer, new Tile(null, new Point(parent.Custom_TilePicker.GetSelected().X, parent.Custom_TilePicker.GetSelected().Y), parent.Custom_TilePicker.GetSelected().Y), oldTile, _x, _y);
                }
                if (e.Button == MouseButtons.Right)
                    Paint_Fill(currentLayer, new Tile(null, new Point(0, 0), (int)Tile.CollisionTypes.NO_COLLISION), oldTile, _x, _y);
            }
            else if (parent.FillType_Stamp.Checked)
            {
                if (e.Button == MouseButtons.Left)
                {
                    if (currentLayer.GetLayerType() == 1)
                    {
                        if (parent.List_Tilesets.SelectedIndex > -1)
                        {
                            LoadedBitmap currentBitmap = parent.List_Tilesets.Items[parent.List_Tilesets.SelectedIndex] as LoadedBitmap;
                            Paint_Brush(currentLayer, new Tile(currentBitmap, new Point(parent.Custom_TilePicker.GetSelected().X, parent.Custom_TilePicker.GetSelected().Y), (int)Tile.CollisionTypes.NO_COLLISION), _x, _y);
                            for (int i = 0; i < parent.Custom_TilePicker.GetAdditionalSelected().Count; i++)
                            {
                                Paint_Brush(currentLayer, new Tile(currentBitmap, new Point(parent.Custom_TilePicker.GetAdditionalSelected()[i].X, parent.Custom_TilePicker.GetAdditionalSelected()[i].Y), (int)Tile.CollisionTypes.NO_COLLISION), _x + (parent.Custom_TilePicker.GetAdditionalSelected()[i].X - parent.Custom_TilePicker.GetSelected().X), _y + (parent.Custom_TilePicker.GetAdditionalSelected()[i].Y - parent.Custom_TilePicker.GetSelected().Y));
                            }
                        }
                    }
                }
                if (e.Button == MouseButtons.Right)
                {
                    Paint_Brush(currentLayer, new Tile(null, new Point(0, 0), (int)Tile.CollisionTypes.NO_COLLISION), _x, _y);
                    for (int i = 0; i < parent.Custom_TilePicker.GetAdditionalSelected().Count; i++)
                    {
                        Paint_Brush(currentLayer, new Tile(null, new Point(0, 0), (int)Tile.CollisionTypes.NO_COLLISION), _x + (parent.Custom_TilePicker.GetAdditionalSelected()[i].X - parent.Custom_TilePicker.GetSelected().X), _y + (parent.Custom_TilePicker.GetAdditionalSelected()[i].Y - parent.Custom_TilePicker.GetSelected().Y));
                    }
                }
            }
            Redraw();
        }
        protected override void OnMouseMove(MouseEventArgs e)
        {
            if (parent.List_Layers.SelectedIndex > -1 && (parent.List_Layers.Items[parent.List_Layers.SelectedIndex] as Layer).GetLayerType() == 0 && parent.Custom_TilePicker.Selected.Y == 3)
                return;
            if (parent.level.spawnPointToAdd == null)
            {
                if (e.Button != MouseButtons.Left && e.Button != MouseButtons.Right)
                    return;
                if (parent.FillType_PaintBucket.Checked)
                    return;
                SetTiles(e);
            }
            base.OnMouseMove(e);
        }
        protected override void OnMouseClick(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left && (parent.List_Layers.Items[parent.List_Layers.SelectedIndex] as Layer).GetLayerType() == 0 && parent.Custom_TilePicker.Selected.Y == 3)
            {
                int _x = (int)((e.X - this.AutoScrollPosition.X) / parent.level.TileWidth);
                int _y = (int)((e.Y - this.AutoScrollPosition.Y) / parent.level.TileHeight);
                if (parent.level.doorToAdd.X == -1 || parent.level.doorToAdd.Y == -1)
                {
                    parent.level.doorToAdd = new Point(_x, _y);
                }
                else
                {
                    (parent.List_Layers.Items[parent.List_Layers.SelectedIndex] as Layer).SetElement(parent.level.doorToAdd.X, parent.level.doorToAdd.Y, null, new Point(0, 3), (int)Tile.CollisionTypes.DOOR, new Point(_x, _y));
                    parent.level.doorToAdd = new Point(-1, -1);
                }
                Redraw();
                return;
            }
            parent.level.doorToAdd = new Point(-1, -1) ;
            if (parent.level.spawnPointToAdd == null)
            {
                for (int i = 0; i < parent.List_SpawnPoints.Items.Count; i++)
                {
                    SpawnPoints spawn = parent.List_SpawnPoints.Items[i] as SpawnPoints;
                    if (parent.Checkbox_ShowSpawnPoints.Checked && (e.X + AutoScrollPosition.X) > spawn.Location.X - 10 && (e.X + AutoScrollPosition.X) < spawn.Location.X + 10 && (e.Y + AutoScrollPosition.Y) > spawn.Location.Y - 10 && (e.Y + AutoScrollPosition.Y) < spawn.Location.Y + 10)
                    {
                        parent.List_SpawnPoints.SelectedIndex = i;
                        if (e.Button == MouseButtons.Right)
                            parent.RemoveSpawnPoint();
                        return;
                    }
                }
                SetTiles(e);
            }
            else
            {
                if (e.Button == MouseButtons.Right)
                {
                    parent.level.spawnPointToAdd = null;
                }
                else
                {
                    SpawnPoints _sp = parent.level.spawnPointToAdd;
                    parent.List_SpawnPoints.Items.Add(new SpawnPoints(new Point(e.X - AutoScrollPosition.X, e.Y - AutoScrollPosition.Y), _sp.Type, _sp.NumberOfSpawns, _sp.TimeBetweenSpanwing));
                    parent.List_SpawnPoints.SelectedIndex = parent.List_SpawnPoints.Items.Count - 1;
                    Redraw();
                }
                parent.SetTooltip();
            }
            base.OnMouseClick(e);
        }
    }
}
